<?php
/**
 * @Author: king
 * @Last Modified by:   king
 * Date: 2018/6/6
 * Time: 17:38
 */

namespace App\Models\Api;
use App\Exceptions\ApiException;
use App\Models\Api\Base;
use Cache;

class MessageCenter extends Base
{
    protected $table = 'message_center';
    protected $dateFormat = 'U';
    public $guarded       = [];
    const CREATED_AT      = 'create_time';
    const UPDATED_AT      = 'update_time';
    public $timestamps    = false;
    const ALLUSERMSGIDS = ':all:user:message:id:';
    const USERMSGIDS = ':user:message:id:';
    const MSGINFO = 'msg:center:info';
    const CACHE_TIME = 86400 * 7;

    /**删除消息中心缓存
     * @param array $map
     * @return bool
     */
    public static function rm_cache($map = [])
    {
        $uid = $map['uid'] ?? 0;//用户id
        $type = $map['type'] ?? 0;//消息类型
        $mid = $map['mid'] ?? 0;//消息id

        if ($mid)
        {
            Cache::forget(self::MSGINFO . $mid);
        }

        if ($uid && $type)
        {
            Cache::forget($uid . self::ALLUSERMSGIDS . $type);
            Cache::forget($uid . self::USERMSGIDS . $type);
        }

        return true;
    }

    /**消息中心添加消息
     * @param array $map
     */
    public function pushMessage($map = [])
    {
        $uid = $map['uid'] ?? 0;
        $r_uid = $map['r_uid'] ?? 0;
        $title = $map['title'] ?? '';
        $content = $map['content'] ?? '';
        $link = $map['link'] ?? '';
        $target = $map['target'] ?? '';

        $reid = $map['reid'] ?? 0;
        $type = $map['type'] ?? 2;
        $cid = $map['cid'] ?? 0;
        //鉴爱成功发送消息
        $messageData = [
            'status' => 0,
            'is_read' => 0,
            'range' => $uid,
            'r_uid'=>$r_uid,
            'type' => $type,
            'reid' => $reid,
            'cid' => $cid,// 年运月运
            'title' => $title,
            'content' => $content,
            'link' => $link,
            'target' => $target,
            'create_time' => time(),
        ];
        try
        {
            $messageData['id'] = self::insertGetId($messageData);

            if ($this->cache_on >= 1)
            {
                //删除用户所有信息id缓存
                self::rm_cache(['uid' => $uid, 'type' => $type, 'mid' => $messageData['id']]);
                //当前用户增加一条信息内容缓存
            }

        }
        catch (\Exception $e)
        {
            \Log::info('写入消息中心失败：' . $e->getMessage());
        }
    }

    /**获取用户所有未读消息id,用户一键已读
     * @param array $map
     * @return array|bool|mixed
     */
    public function getAllUserMessage($map = [])
    {
        switch ($map['type'])
        {
            case 1:
                $where['type'] = 1;
                break;
            case 2:
                $where['type'] = 2;
                 break;
            case 3:
                $where['type'] = 3;
        }
        $where['is_read'] = 0;

        $uid = $map['uid'];

        $mid = false;

        if (intval($this->cache_on >= 1) && Cache::has($uid . self::ALLUSERMSGIDS . $map['type']))
        {
            $mid = Cache::get($uid . self::ALLUSERMSGIDS . $map['type']);
        }

        // 获取当前消息的所有消息的id
        if ($mid === false)
        {
            try
            {
                $mid = $this
                    ->where($where)
                    ->where('range',$map['uid'])
                    ->orWhere('range',0)
                    ->orderBy('create_time', 'DESC')
                    ->get(['id']);
                // 缓存消息id,根据消息id
                if ($this->cache_on >= 1)
                    Cache::set($uid . self::ALLUSERMSGIDS . $map['type'], $mid, self::CACHE_TIME);

            }
            catch (\Exception $e)
            {
                $mid = [];// 消息列表默认为空
            }

        }


        return $mid;
    }


    /**获取当前用户的系统 / 服务消息id(有分页)
     * @param array $map
     * @return array
     */
    public function get_user_msg_id($map = [])
    {
        switch ($map['type'])
        {
            case 1:
                $where['type'] = 1;
                break;
            case 2:
                $where['type'] = 2;
                 break;
            case 3:
                $where['type'] = 3;
        }
        $where['status'] = 0;

        $uid = $map['uid'];
        $page = isset($map['page']) && $map['page'] ? $map['page'] : 1;

        $mid = false;

        if ($this->cache_on >= 1 &&  Cache::has($uid . self::USERMSGIDS . $map['type']))
        {
            $mid = Cache::get($uid . self::USERMSGIDS . $map['type']);
        }

        // 获取当前消息的所有消息的id
        if ($mid === false)
        {
            try
            {
                $data1 = $this
                    ->where($where)
                    ->where('range',$map['uid'])
                    ->orWhere('range',0)
                    ->pluck('id')->toArray();
                // 将消息id组成字符串
                if (!empty($data1)) $mid = implode(',', $data1);
                else $mid = '';

                // 缓存消息id,根据消息id
                if ($this->cache_on >= 1)
                    Cache::set($uid . self::USERMSGIDS . $map['type'], $mid, self::CACHE_TIME);

            }
            catch (\Exception $e)
            {
                $mid = '';// 消息列表默认为空
            }

        }

        // 将消息id转为数组
        $mid = explode(',', $mid);
        $per_page = 10;// 当前消息消息每页显示数量
        if(empty($mid[0])){
        // 统计有多少消息
        $total = 0;
        }else{
        $total = count($mid);
        }
        //获取数据分页信息
        $data_list = getPaginatorData($total, $page, $per_page);

        //获取分页后的消息id数组
        $mids = array_slice($mid, $data_list['start'], $per_page);
       

        unset($data_list['start']);
        unset($data_list['end']);
        //获取消息详细内容
        $data_list['data'] = $this->get_msg_info(['ids' => $mids]);

        //将数据根据创建时间排序,因查看消息后会更新缓存影响数据
        array_multisort(array_column($data_list['data'], 'create_time'), SORT_NUMERIC, SORT_DESC, $data_list['data']);
        return $data_list;
    }


    /**获取消息中心详情
     * @param array $map
     * @return array
     */
    public function get_msg_info($map = [])
    {
        $ids = $map['ids'];

        $data = [];
        // 根据当前页消息id获取所需的消息内容
        if (!empty($ids))
        {
            $ac_ids = '';
            $temp = [];

            // 从缓存消息内容,根据消息id
            foreach ($ids as $ac_id)
            {
                if (intval($this->cache_on >= 1) && Cache::has(self::MSGINFO . $ac_id))
                {
                    // 根据消息id 获取消息内容
                    $temp[$ac_id] = Cache::get(self::MSGINFO . $ac_id);
                } else
                {
                    $temp[$ac_id] = false;
                }

                // 消息内容未缓存，等待从数据库中获取
                if ($temp[$ac_id] === false)
                {
                    $ac_ids .= ',' . $ac_id;
                    unset($temp[$ac_id]);
                }
            }

            // 从数据库获取消息内容
            if ($ac_ids != '')
            {
                // 去掉开头的,
                $ac_ids = substr($ac_ids, 1);
                $ac_ids = explode(',', $ac_ids);
                try
                {
                   $contens = $this
                        ->select('id','range','r_uid','type','cid','title','content','link','target','create_time','status','is_read')
                        ->whereIn('id',$ac_ids)
                        ->orderBy('create_time', 'DESC')
                        ->get();
                    $contens = json_decode(json_encode($contens, true), true);
                }
                catch (\Exception $e)
                {
                    $contens = [];
                }

                if (!empty($contens))
                {
                    foreach ($contens as $c)
                    {
                        // 将消息内容缓存
                        if ($this->cache_on >= 1)
                            Cache::set(self::MSGINFO . $c['id'], $c, self::CACHE_TIME);
                        // 将数据库查出来的内容 写入到数组中为空的部分
                        $temp[$c['id']] = $c;
                    }
                }
            }

            foreach ($temp as $t)
            {
                $data[] = $t;
            }
        }

        return $data;
    }


}